package lxs.swift.tool;


import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;

public interface IOStreamer extends Closeable {

    void transfer();

    @Override
    void close();

    static IOStreamer of(InputStream inputStream, OutputStream outputStream) {
        Objects.requireNonNull(inputStream);
        Objects.requireNonNull(outputStream);
        return new IOStreamer() {
            @Override
            public void transfer() {
                try {
                    try {
                        byte[] bytes = new byte[1024];//存储读取到的多少字节
                        int len;
                        while ((len = inputStream.read(bytes)) != -1) {
                            outputStream.write(bytes, 0, len);
                        }
                        outputStream.flush();
                    } catch (Exception e) {
                        inputStream.close();
                        outputStream.close();
                        throw e;
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            @Override
            public void close() {
                try {
                    inputStream.close();
                    outputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    }

    static IOStreamer of(Reader reader, Writer writer) {
        Objects.requireNonNull(reader);
        Objects.requireNonNull(writer);
        return new IOStreamer() {
            @Override
            public void transfer() {
                try {
                    try {
                        char[] chars = new char[1024];//存储读取到的多少字节
                        int len;
                        while ((len = reader.read(chars)) != -1) {
                            writer.write(chars, 0, len);
                        }
                        writer.flush();
                    } catch (Exception e) {
                        reader.close();
                        writer.close();
                        throw e;
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            @Override
            public void close() {
                try {
                    reader.close();
                    writer.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    }


    static byte[] toBytes(InputStream inputStream) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        IOStreamer streamer = IOStreamer.of(inputStream, byteArrayOutputStream);
        streamer.transfer();
        streamer.close();
        return byteArrayOutputStream.toByteArray();
    }

    static void toFile(InputStream inputStream, Path path) {
        try {
            OutputStream outputStream = Files.newOutputStream(path);
            IOStreamer streamer = IOStreamer.of(inputStream, outputStream);
            streamer.transfer();
            streamer.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
